<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>
        // 高阶函数 一个函数的参数中含有一个函数
        // 高阶函数便于扩展
        function test(a, b, fn) {
            return fn(a) + fn(b)
        }

        function square(x) {
            return Math.pow(x, 3)
        }
        console.log(test(2, 2, square));

        // 柯里化
        function test(a, b, c) {
            return a + b + c;
        }
        test(1, 2, 3);
        // test(1, 2)(3);
        // 1.简化代码，
        // 2.提高维护性
        // 3.功能单一化
        // 功能内聚
        // 降低耦合
        // 降低代码的重复性
        // 提高代码的适应性
        function add(a, b, c, d) {
            return a + b + c + d;
        }

        function curry(fn) {
            var _arg = [].slice.call(arguments, 1)
            return function() {
                var newArg = _arg.concat([].slice.call(arguments))
                return fn.apply(this, newArg)
            }
        }
        // var add2 = curry(add, 1, 5);
        // console.log(add2(2, 3));

        function curry1(fn, len) {
            var len = len || fn.length;
            console.log(12312);
            console.log(len);
            console.log(fn);
            var func = function(fn) {
                var _arg = [].slice.call(arguments, 1);
                console.log('_arg');
                console.log(_arg);
                return function() {
                    var newArgs = _arg.concat([].slice.call(arguments));
                    return fn.apply(this, newArgs)
                }
            }
            return function() {
                var argLen = arguments.length;
                console.log('len');
                console.log(len);
                console.log(argLen);
                console.log(arguments);
                if (argLen < len) {
                    var formatedArr = [fn].concat([].slice.call(arguments));
                    console.log('formatedArr');
                    console.log(formatedArr);
                    console.log(func.apply(this, formatedArr));
                    return curry1(func.apply(this, formatedArr), len - argLen)
                } else {
                    console.log('arguments');
                    console.log(arguments);
                    return fn.apply(this, arguments)
                }
            }
        }
        var add12 = curry1(add);
        console.log(add12);
        console.log(add12(1)(2)(3)(4));


        //事件兼容
        var addEvent = (function() {
            if (window.addEventListener) {
                return function(el, type, fn, capture) {
                    el.addEventListener(type, fn, capture)
                }
            } else if (window.attachEvent) {
                return function(el, type, fn) {
                    el.attachEvent(type, fn);
                }
            } else {
                return function(el, type, fn) {
                    el['on' + type] = fn
                }
            }
        })()
    </script>
</body>

</html>